async function GuessZprj(uri: string) {
  let ret = await getZprjJson(uri);
  if (ret != false) {
    return ret;
  }

  ret = await getZprj(uri);
  if (ret != false) {
    return ret;
  }

  ret = await getTilesetZprj(uri);
  if (ret != false) {
    return ret;
  }

  return false;
}

async function getZprjJson(uri: string) {
  try {
    const zprj_uri = uri.substring(0, uri.length - 5) + '_zprj.json';
    const data = await fetch(zprj_uri);
    if (data.status != 200) {
      return false;
    }
    const dataJson = await data.json();
    return dataJson;
  } catch (_e) {
    return false;
  }
}

async function getZprj(uri: string) {
  try {
    const zprj_uri = uri.substring(0, uri.length - 5) + '.zprj';
    const data = await fetch(zprj_uri);
    if (data.status != 200) {
      return false;
    }
    const dataJson = await data.json();
    return dataJson;
  } catch (_e) {
    return false;
  }
}

function isNotZero(data: string | number) {
  return Math.abs(Number(data)) < 0.0001;
}

async function getTilesetZprj(uri: string) {
  try {
    const data = await fetch(uri);
    if (data.status != 200) {
      return false;
    }
    const dataJson = await data.json();
    const arrTransform = dataJson?.root?.transform;
    if (Array.isArray(arrTransform) && arrTransform.length == 16) {
      const transX = Number(arrTransform[12]);
      const transY = Number(arrTransform[13]);
      if (isNotZero(transX) && isNotZero(transY)) {
        return {
          zprj: {
            way: 'manual',
            x: transX,
            y: transY
          }
        };
      }
    }

    const box = dataJson?.root?.boundingVolume?.box;
    if (Array.isArray(arrTransform)) {
      const transX = Number(box[0]);
      const transY = Number(box[1]);
      if (isNotZero(transX) && isNotZero(transY)) {
        return {
          zprj: {
            way: 'manual',
            x: transX,
            y: transY
          }
        };
      }
    }
  } catch (_e) {
    return false;
  }

  return false;
}

export { GuessZprj };
